<?php


namespace app\api\service;


class YiLianYun{
//$partner = 1054608861;
//$apiKey = '999ac90bc42866a20bcce95d4d27ce14';
//$machine_code = 4004558431;
//$msign = 'd4ubhqzxvvr4';
//$grantType = 'client_credentials';  //自有模式(client_credentials) || 开放模式(authorization_code)
//$scope = 'all';                     //权限
//$timesTamp = time();                //当前服务器时间戳(10位)

    private $partner = '';//应用id
    private $apiKey = '';//apiKey
    private $machine_code = '';//设备终端号，打印机终端号
    private $msign = '';//打印机密钥
    private $grantType = '';
    private $scope = '';//权限 一般为固定值all
    private $timesTamp = '';

    public function __construct(){
        $this->partner = config('YiLianYun.partner');
        $this->apiKey = config('YiLianYun.apiKey');
        $this->machine_code = config('YiLianYun.machine_code');
        $this->msign = config('YiLianYun.msign');
        $this->grantType = config('YiLianYun.grantType');
        $this->scope = config('YiLianYun.scope');
        $this->timesTamp = time();

    }

    //获取token，用于调用打印
    public function getPrit(){
       /**
        * 获取token,由于token是多人使用的，
        * 所有第一次获取到的token，要存入到文件中，便于下次使用，类似于存在缓存
        */

       $dir = EXTEND_PATH.'yiToken.txt';
       if(is_file($dir)){//token文件生成过获取文件中的数据
           $tokenTamp = json_decode(file_get_contents($dir),true);
           $expires_time = $tokenTamp['expires_time'];
           if((time() - $expires_time) > 0 ){//token过去，要重新申请token
               $refresh_token = $tokenTamp['body']['refresh_token'];
               $tokenTamps = $this->refreshToken($this->partner,$this->timesTamp,$this->apiKey,$this->scope,$refresh_token);

               $tokenTamp = json_decode($tokenTamps,true);
               if($tokenTamp['error'] != 0){
                   die(json_encode(['msg'=>$tokenTamp['error_description']]));
               }
               $tokenTamp['expires_time'] = (int)$tokenTamp['body']['expires_in'] + time();
               $tokenTamp = json_encode($tokenTamp);
               file_put_contents($dir,$tokenTamp);
           }
       }else{
           $tokenTamp = $this->getToken($this->partner,$this->apiKey,$this->grantType,$this->scope,$this->timesTamp);
           $tokenTamp = json_decode($tokenTamp,true);
           if($tokenTamp['error'] != 0){
               die(json_encode(['msg'=>$tokenTamp['error_description']]));
           }

           //计算出access_token的过期时间 生成时间 + 过期时间时间设定(2小时候过期);
           $tokenTamp['expires_time'] = (int)$tokenTamp['body']['expires_in'] + time();
           $tokenTamp = json_encode($tokenTamp);
           file_put_contents($dir,$tokenTamp);
       }

       //获取token值
       $accessToken = $tokenTamp['body']['access_token'];
       $content = $this->setContent();
       $sign = $this->getSign($this->partner,$this->timesTamp,$this->apiKey);
       $this->printData($this->partner,$this->timesTamp,$this->machine_code,$accessToken,$content,1,$sign);
    }

    //获取sign
    private function getSign($partner, $timesTamp, $apiKey)
    {
        return md5($partner . $timesTamp . $apiKey);
    }

    //获取uuid
    private function Uuid4()
    {
        mt_srand((double)microtime() * 10000);
        $charid = strtolower(md5(uniqid(rand(), true)));
        $hyphen = '-';
        $uuidv4 =
            substr($charid, 0, 8) . $hyphen .
            substr($charid, 8, 4) . $hyphen .
            substr($charid, 12, 4) . $hyphen .
            substr($charid, 16, 4) . $hyphen .
            substr($charid, 20, 12);
        return $uuidv4;
    }

    //获取字符串
    private function getStr($data)
    {
        $str = '';
        foreach ($data as $key => $value) {
            $str = $str . $key . '=' . $value . '&';
        }
        return rtrim($str, '&');

    }

    //发送请求
    private function curlSend($requestInfo, $url){
        $curl = curl_init(); // 启动一个CURL会话
        curl_setopt($curl, CURLOPT_URL, $url); // 要访问的地址
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0); // 对认证证书来源的检测
        curl_setopt($curl, CURLOPT_HTTPHEADER, array(
            'Expect:'
        )); // 解决数据包大不能提交
        curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); // 使用自动跳转
        curl_setopt($curl, CURLOPT_AUTOREFERER, 1); // 自动设置Referer
        curl_setopt($curl, CURLOPT_POST, 1); // 发送一个常规的Post请求
        curl_setopt($curl, CURLOPT_POSTFIELDS, $requestInfo); // Post提交的数据包
        curl_setopt($curl, CURLOPT_TIMEOUT, 30); // 设置超时限制防止死循
        curl_setopt($curl, CURLOPT_HEADER, 0); // 显示返回的Header区域内容
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); // 获取的信息以文件流的形式返回
        $tmpInfo = curl_exec($curl); // 执行操作
        if (curl_errno($curl)) {
            echo 'Errno' . curl_error($curl);
        }
        curl_close($curl); // 关键CURL会话
        return $tmpInfo; // 返回数据
    }

    //调用打印机接口
    private function printData($partner,$timesTamp,$machineCode,$accessToken,$content,$originId,$sign){
        $url = 'https://open-api.10ss.net/print/index';
        $data = array(
            'client_id' => $partner,
            'sign' => $sign,
            'id' => $this->Uuid4(),
            'machine_code' => $machineCode,
            'access_token' => $accessToken,
            'content' => $content,
            'origin_id' => $originId,
            'timestamp' => $timesTamp,
        );
        $str = $this->getStr($data);
        return  $this->curlSend($str,$url);
    }

    //生成token
    private function getToken($partner,$apiKey,$grantType,$scope,$timesTamp){
        $url = 'https://open-api.10ss.net/oauth/oauth';
        $requestAll = array(
            'client_id' => $partner,
            'sign' => $this->getSign($partner, $timesTamp, $apiKey),
            'id' => $this->Uuid4(),
            'grant_type' => $grantType,
            'scope' => $scope,
            'timestamp' => $timesTamp,
        );

        return  $this->curlSend($this->getStr($requestAll),$url);

    }

    //token过期重新重新生成token
    private function  refreshToken($partner,$timesTamp,$apiKey,$scope,$RefreshToken){
        $url = 'https://open-api.10ss.net/oauth/oauth';
        $requestAll = [
            'client_id' => $partner,
            'sign' => $this->getSign($partner,$timesTamp,$apiKey),
            'id' =>  $this->Uuid4(),
            'grant_type' => 'refresh_token',
            'scope' => $scope,
            'refresh_token' => $RefreshToken,
            'timestamp' => $timesTamp,
        ];
        return $this->curlSend($this->getStr($requestAll),$url);
    }

    //处理打印的内容
    private function setContent(){
        $content = '';
        $content .="<FS><center>luge测试打印</center></FS>\n";
        $content .="订单号：SH20180512001\n";
        $content .="订单生成时期:201805121002\n";
        $content .= str_repeat('-',32)."\n";

        $content .="<FS><table><tr><td>名称</td><td>数量</td><td>金额</td></tr>";
        $content .="<tr><td>这是测试商品名称的多度的越长越好，所以我会一直歇息去的</td>";
        $content .="<td> x 2</td><td>99.00</td></tr>";
        $content .="</table></FS>";
        return $content;
    }


}



